package com.freeLearning.boot.course.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.freeLearning.boot.common.annotation.Log;
import com.freeLearning.boot.common.enums.LogModuleEnum;
import com.freeLearning.boot.common.result.Result;
import com.freeLearning.boot.core.security.util.SecurityUtils;
import com.freeLearning.boot.course.mapper.CourseLikeMapper;
import com.freeLearning.boot.course.model.VO.CourseChaptersVO;
import com.freeLearning.boot.course.model.VO.UserCourseWatchVO;
import com.freeLearning.boot.course.model.entity.*;
import com.freeLearning.boot.course.model.query.ByConsultantIdPageQuery;
import com.freeLearning.boot.course.model.query.ByUserQuery;
import com.freeLearning.boot.course.service.CourseChaptersService;
import com.freeLearning.boot.course.service.CourseInfoService;
import com.freeLearning.boot.course.service.UserCourseChapterService;
import com.freeLearning.boot.course.service.UserCourseService;
import com.freeLearning.boot.course.service.impl.UserCourseServiceImpl;
import com.freeLearning.boot.system.enums.MessageEnum;
import com.freeLearning.boot.system.model.entity.Message;
import com.freeLearning.boot.system.model.entity.User;
import com.freeLearning.boot.system.service.MessageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.poi.hpsf.Decimal;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import static cn.hutool.poi.excel.sax.AttributeName.r;

@Tag(name = "23.课程用户接口")
@RequestMapping("/api/v1/userCourse")
@RestController
@RequiredArgsConstructor
public class UserCourseController {
    private final UserCourseService userCourseService;
    private final CourseChaptersService courseChaptersService;
    private final UserCourseChapterService userCourseChapterService;
    private final CourseLikeMapper courseLikeMapper;
    private final MessageService messageService;
    private final CourseInfoService courseInfoService;

    @PostMapping("/queryByConsultant/page")
    @Operation(summary = "分页根据咨询师 id 查询收藏课程的用户")
    @Log(value = "分页查询课程", module = LogModuleEnum.USER_COURSE)
    public Result<IPage<UserCourse>> queryByConsultant(@RequestBody ByConsultantIdPageQuery query) {
        return Result.success(userCourseService.queryByConsultantPage(query));
    }

    @PostMapping("/queryByUser")
    @Operation(summary = "根据用户 id 查询收藏的课程")
    @Log(value = "查询用户收藏的课程", module = LogModuleEnum.USER_COURSE)
    public Result<List<UserCourse>> queryByUser(@RequestBody ByUserQuery query) {
        Long userId = SecurityUtils.getUserId();
        List<UserCourse> list = userCourseService.list(
                new LambdaQueryWrapper<UserCourse>()
                        .eq(UserCourse::getUserId, userId)
                        .eq(query.getCategoryId() != null, UserCourse::getCategoryId, query.getCategoryId())
                        .eq(query.getStatus() != null, UserCourse::getStatus, query.getStatus())
                        .like(query.getKeyword() != null && !query.getKeyword().equals(""), UserCourse::getCourseName, query.getKeyword())
                        .or()
                        .like(query.getKeyword() != null && !query.getKeyword().equals(""), UserCourse::getConsultantName, query.getKeyword())
        );
        return Result.success(list);
    }

    @PostMapping("/add")
    @Operation(summary = "新增课程用户")
    @Log(value = "新增课程用户", module = LogModuleEnum.USER_COURSE)
    public Result<Boolean> add(@RequestBody UserCourse userCourse) {
        userCourse.setUserId(SecurityUtils.getUserId());
        userCourse.setUserName(SecurityUtils.getNickName());
        return Result.success(userCourseService.save(userCourse));
    }

    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除课程用户")
    @Log(value = "删除课程用户", module = LogModuleEnum.USER_COURSE)
    public Result<Boolean> delete(@PathVariable Long id) {
        return Result.success(userCourseService.removeById(id));
    }
    @PostMapping("/deleteByUserIdAndCourseId")
    @Operation(summary = "根据用户 id 和课程 id 删除课程用户")
    @Log(value = "根据用户 id 和课程 id 删除课程用户", module = LogModuleEnum.USER_COURSE)
    public Result<Boolean> deleteByUserIdAndCourseId(@RequestBody UserCourse userCourse) {
        return Result.success(userCourseService.remove(new LambdaQueryWrapper<UserCourse>()
                .eq(UserCourse::getUserId, SecurityUtils.getUserId())
                .eq(UserCourse::getCourseId, userCourse.getCourseId())
        ));
    }

    @PutMapping("/update")
    @Operation(summary = "更新课程用户")
    @Log(value = "更新课程用户", module = LogModuleEnum.USER_COURSE)
    public Result<Boolean> update(@RequestBody UserCourse userCourse) {
        List<UserCourseChapter> userCourseChapterList = userCourseChapterService.list(new LambdaQueryWrapper<UserCourseChapter>()
                .eq(UserCourseChapter::getUserId, userCourse.getUserId())
                .eq(UserCourseChapter::getCourseId, userCourse.getCourseId())
        );
        BigDecimal progress = new BigDecimal(0);
        for (UserCourseChapter userCourseChapter : userCourseChapterList) {
            progress = progress.add(userCourseChapter.getProgress());
        }
        List<CourseChapters> chapters = courseChaptersService.list(new LambdaQueryWrapper<CourseChapters>()
                .eq(CourseChapters::getCourseId, userCourse.getCourseId())
        );
        BigDecimal divide = progress.divide(new BigDecimal(chapters.size()));
        userCourse.setProgress(divide);
        userCourse.setStatus(divide.equals(BigDecimal.ZERO) ? 0 : divide.equals(BigDecimal.ONE) ? 2 : 1);
        boolean update = userCourseService.update(new LambdaUpdateWrapper<UserCourse>()
                .eq(UserCourse::getId, userCourse.getId())
                .set(UserCourse::getProgress, userCourse.getProgress())
                .set(UserCourse::getStatus, userCourse.getStatus())
                .set(userCourse.getLearningDuration() !=null, UserCourse::getLearningDuration,userCourse.getLearningDuration())
                .set(userCourse.getLastLearnTime()!= null,UserCourse::getLastLearnTime,userCourse.getLastLearnTime())
                .set(userCourse.getCurrentChapter() != null,UserCourse::getCurrentChapter,userCourse.getCurrentChapter())
                .set(UserCourse::getUpdateTime, LocalDateTime.now())
        );
        return Result.success(update);

    }

    @PostMapping("/checkUserHasCourse")
    @Operation(summary = "检查用户是否已经收藏过课程")
    @Log(value = "检查用户是否已经收藏过课程", module = LogModuleEnum.USER_COURSE)
    public Result<Boolean> checkUserHasCourse(@RequestBody UserCourse userCourse) {
        Long userId = SecurityUtils.getUserId();
        if (userId == null){
            return  Result.success(false);
        }
        UserCourse one = userCourseService.getOne(new LambdaQueryWrapper<UserCourse>()
                .eq(UserCourse::getUserId, userId)
                .eq(UserCourse::getCourseId, userCourse.getCourseId())
        );
        return Result.success(one != null);
    }

    @Operation(summary = "查询用户课程观看情况")
    @GetMapping("/queryUserCourseWatchStatus/{courseId}")
    public Result<UserCourseWatchVO> queryUserCourseWatchStatus(@PathVariable Long courseId) {
        Long userId = SecurityUtils.getUserId();
        UserCourse userCourse = userCourseService.getOne(new LambdaQueryWrapper<UserCourse>()
                .eq(userId != null, UserCourse::getUserId, userId)
                .eq(courseId != null, UserCourse::getCourseId, courseId)
        );
        Assert.isTrue(userCourse != null, "用户未收藏该课程");
        CourseLike courseLike = courseLikeMapper.selectOne(
                new LambdaQueryWrapper<CourseLike>()
                        .eq(CourseLike::getUserId, userId)
                        .eq(CourseLike::getCourseId, courseId));
        UserCourseWatchVO userCourseWatchVO = BeanUtil.copyProperties(userCourse, UserCourseWatchVO.class);
        userCourseWatchVO.setIsLike(!Objects.isNull(courseLike));
        userCourseWatchVO.setLikeCount(courseLikeMapper.selectCount(new LambdaQueryWrapper<CourseLike>()
                .eq(CourseLike::getCourseId, courseId)));
        List<CourseChaptersVO> list = courseChaptersService.list(new LambdaQueryWrapper<CourseChapters>()
                .eq(CourseChapters::getCourseId, courseId)).stream().map(item->{
            CourseChaptersVO courseChaptersVO = BeanUtil.copyProperties(item, CourseChaptersVO.class);
            UserCourseChapter courseChapter = userCourseChapterService.getOne(new LambdaQueryWrapper<UserCourseChapter>()
                    .eq(UserCourseChapter::getUserId, userId)
                    .eq(UserCourseChapter::getChapterId, item.getId())
                    .eq(UserCourseChapter::getCourseId, courseId)
            );
            courseChaptersVO.setProgress(courseChapter != null ? courseChapter.getProgress() : BigDecimal.ZERO);
            return courseChaptersVO;
        }).toList();
        userCourseWatchVO.setChaptersNum(list.size());
        userCourseWatchVO.setChapters(list);
        return Result.success(userCourseWatchVO);
    }

    @GetMapping("/queryChapterProgress/{chapterId}")
    @Operation(summary = "查询用户章节观看进度")
    public Result<UserCourseChapter> queryChapterProgress(@PathVariable Long chapterId) {
        Long userId = SecurityUtils.getUserId();
        UserCourseChapter one = userCourseChapterService.getOne(new LambdaQueryWrapper<UserCourseChapter>()
                .eq(UserCourseChapter::getUserId, userId)
                .eq(UserCourseChapter::getChapterId, chapterId)
        );
        if (one == null){
            one = new UserCourseChapter();
            one.setProgress(BigDecimal.ZERO);
            one.setChapterId(chapterId);
            one.setUserId(userId);
            userCourseChapterService.save(one);
        }
        return Result.success(one);
    }
    @PostMapping("/updateProgress")
    @Operation(summary = "更新用户章节观看进度")
    public Result<Boolean> updateProgress(@RequestBody UserCourseChapter userCourseChapter) {
        Long userId = SecurityUtils.getUserId();
        UserCourseChapter one = userCourseChapterService.getOne(new LambdaQueryWrapper<UserCourseChapter>()
                .eq(UserCourseChapter::getUserId, userId)
                .eq(UserCourseChapter::getChapterId, userCourseChapter.getChapterId())
        );
        if (one != null &&   one.getProgress().equals(BigDecimal.ONE)){
            return Result.success(true);
        }
        if (one == null){
            userCourseChapter.setUserId(userId);
            boolean save = userCourseChapterService.save(userCourseChapter);
            return Result.success(save);
        }
        boolean update = userCourseChapterService.update(new UpdateWrapper<UserCourseChapter>()
                .eq("user_id", userId)
                .eq("chapter_id", userCourseChapter.getChapterId())
                .set("progress", userCourseChapter.getProgress())
        );
        return Result.success(update);
    }

    @Operation(summary = "用户点赞|取消点赞课程")
    @PostMapping("/like/{courseId}")
    public Result<Boolean> like(@PathVariable Long courseId) {
        Long userId = SecurityUtils.getUserId();
        CourseLike courseLike = new CourseLike();
        courseLike.setCourseId(courseId);
        courseLike.setUserId(userId);
        CourseLike one = courseLikeMapper.selectOne(new LambdaQueryWrapper<CourseLike>()
                .eq(CourseLike::getCourseId, courseId)
                .eq(CourseLike::getUserId, userId)
        );
        if (one == null){
            int insert = courseLikeMapper.insert(courseLike);
            CourseInfo courseInfo = courseInfoService.getById(courseId);
            Message message = Message.builder()
                    .title("课程《" + courseInfo.getTitle()+"》收到一个点赞")
                    .content("用户“" + SecurityUtils.getNickName()+"”点赞了您的课程《"+courseInfo.getTitle()+"》;")
                    .type(MessageEnum.LIKE.getValue())
                    .publisherId(userId)
                    .publishTime(LocalDateTime.now())
                    .createBy(userId)
                    .acceptId(courseInfo.getConsultantId())
                    .build();
            messageService.sendMessage(message);
            return Result.success(insert > 0);
        }else {
            int delete = courseLikeMapper.delete(new LambdaQueryWrapper<CourseLike>()
                    .eq(CourseLike::getCourseId, courseId)
                    .eq(CourseLike::getUserId, userId)
            );
            return Result.success(delete > 0);
        }
    }
}
